package com.lh0811.forge.pserv.basic.server.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lh0811.forge.dependency.basic_code.BeanHelper;
import com.lh0811.forge.dependency.basic_code.IdWorker;
import com.lh0811.forge.dependency.basic_web.exception.CommonException;
import com.lh0811.forge.dependency.basic_web.response.ServerResponse;
import com.lh0811.forge.dependency.security.client.component.SecurityUtil;
import com.lh0811.forge.dependency.security.core.model.entity.SecurityAuthority;
import com.lh0811.forge.pserv.basic.api.param.*;
import com.lh0811.forge.pserv.basic.api.vo.CommDictQueryVo;
import com.lh0811.forge.pserv.basic.api.vo.CommDictTypeVo;
import com.lh0811.forge.pserv.basic.server.repository.dao.CommDictDao;
import com.lh0811.forge.pserv.basic.server.repository.dao.CommDictTypeDao;
import com.lh0811.forge.pserv.basic.server.repository.entity.CommDict;
import com.lh0811.forge.pserv.basic.server.repository.entity.CommDictType;
import com.lh0811.forge.pserv.basic.server.service.CommDictService;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class CommDictServiceImpl implements CommDictService {

    @Resource
    private CommDictTypeDao commDictTypeDao;

    @Resource
    private CommDictDao commDictDao;

    @Override
    public PageInfo<CommDictTypeVo> dictTypeQueryPage(CommDictTypeQueryPageParam param) throws Exception {
        PageHelper.startPage(param.getPageNum(), param.getPageSize());
        List<CommDictType> list = commDictTypeDao.lambdaQuery()
                .like(StringUtils.isNotBlank(param.getDictTypeKey()), CommDictType::getDictTypeKey, param.getDictTypeKey())
                .like(StringUtils.isNotBlank(param.getDictTypeName()), CommDictType::getDictTypeName, param.getDictTypeName())
                .orderByDesc(CommDictType::getCreateTime)
                .list();
        PageInfo pageInfo = new PageInfo<>(list);
        PageHelper.clearPage();
        pageInfo.setList(BeanHelper.copyList(pageInfo.getList(), CommDictTypeVo.class));
        return pageInfo;
    }

    @Override
    public List<CommDictTypeVo> dictTypeQueryList(CommDictTypeQueryListParam param) throws Exception {
        List<CommDictType> list = commDictTypeDao.lambdaQuery()
                .like(StringUtils.isNotBlank(param.getDictTypeKey()), CommDictType::getDictTypeKey, param.getDictTypeKey())
                .list();
        return BeanHelper.copyList(list, CommDictTypeVo.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dictTypeCreate(CommDictTypeCreateParam param) throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        CommDictType commDictType = commDictTypeDao.lambdaQuery()
                .eq(CommDictType::getDictTypeKey, param.getDictTypeKey())
                .one();
        if (ObjectUtils.isNotEmpty(commDictType)) {
            throw CommonException.create(ServerResponse.createByError("字典类型已经存在"));
        }
        CommDictType newDictType = new CommDictType();
        newDictType.setId(IdWorker.nextId()); // 主键
        newDictType.setDictTypeKey(param.getDictTypeKey()); // 字典类型
        newDictType.setDictTypeName(param.getDictTypeName()); // 字段类型名称
        newDictType.setCreateTime(new Date()); // 创建时间
        newDictType.setCreateBy(Long.valueOf(securityAuthority.getUserId())); // 创建人
        commDictTypeDao.save(newDictType);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dictTypeUpdate(CommDictTypeUpdateParam param) throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        CommDictType commDictType = commDictTypeDao.getById(param.getId());
        if (ObjectUtils.isEmpty(commDictType)) {
            throw CommonException.create(ServerResponse.createByError("字典类型不存在"));
        }
        commDictTypeDao.lambdaUpdate()
                .set(CommDictType::getDictTypeKey, param.getDictTypeKey())
                .set(CommDictType::getDictTypeName, param.getDictTypeName())
                .set(CommDictType::getUpdateTime, new Date())
                .set(CommDictType::getUpdateBy, Long.valueOf(securityAuthority.getUserId()))
                .eq(CommDictType::getId, commDictType.getId())
                .update();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void dictTypeDelete(Long dictTypeId) throws Exception {
        CommDictType commDictType = commDictTypeDao.getById(dictTypeId);
        if (ObjectUtils.isEmpty(commDictType)) {
            throw CommonException.create(ServerResponse.createByError("字典类型不存在"));
        }
        commDictTypeDao.removeById(dictTypeId);
        commDictDao.lambdaUpdate().eq(CommDict::getTypeId, dictTypeId).remove();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void dictCreate(CommDictCreateParam param) throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        CommDict commDictExit = commDictDao.lambdaQuery()
                .eq(CommDict::getTypeId, param.getTypeId())
                .eq(CommDict::getDictKey, param.getDictKey())
                .one();
        if (ObjectUtils.isNotEmpty(commDictExit)) {
            throw CommonException.create(ServerResponse.createByError(ServerResponse.createByError("字典信息已存在")));
        }
        CommDict commDict = new CommDict();
        commDict.setId(IdWorker.nextId()); // 字典id
        commDict.setTypeId(param.getTypeId()); // 字典类型
        commDict.setDictKey(param.getDictKey()); // 字典键
        commDict.setDictValue(param.getDictValue()); // 字典值
        commDict.setCreateTime(new Date()); // 创建时间
        commDict.setCreateBy(Long.valueOf(securityAuthority.getUserId())); // 创建人
        commDictDao.save(commDict);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void dictDelete(Long id) throws Exception {
        CommDict commDict = commDictDao.getById(id);
        if (ObjectUtils.isEmpty(commDict)) {
            throw CommonException.create(ServerResponse.createByError("字典不存在"));
        }
        commDictDao.removeById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void dictUpdate(CommDictUpdateParam param) throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();

        CommDict commDict = commDictDao.getById(param.getId());
        if (ObjectUtils.isEmpty(commDict)) {
            throw CommonException.create(ServerResponse.createByError("字典不存在"));
        }

        commDictDao.lambdaUpdate()
                .set(ObjectUtils.isNotEmpty(param.getTypeId()), CommDict::getTypeId, param.getTypeId())
                .set(StringUtils.isNotBlank(param.getDictKey()), CommDict::getDictKey, param.getDictKey())
                .set(StringUtils.isNotBlank(param.getDictValue()), CommDict::getDictValue, param.getDictValue())
                .set(CommDict::getUpdateTime, new Date())
                .set(CommDict::getUpdateBy, Long.valueOf(securityAuthority.getUserId()))
                .eq(CommDict::getId, param.getId())
                .update();
    }

    @Override
    public PageInfo<CommDictQueryVo> dictQueryPage(CommDictQueryPageParam param) throws Exception {
        PageHelper.startPage(param.getPageNum(), param.getPageSize());
        List<CommDict> list = commDictDao.lambdaQuery()
                .eq(ObjectUtils.isNotEmpty(param.getTypeId()), CommDict::getTypeId, param.getTypeId())
                .like(StringUtils.isNotBlank(param.getDictKey()), CommDict::getDictKey, param.getDictKey())
                .like(StringUtils.isNotBlank(param.getDictValue()), CommDict::getDictValue, param.getDictValue())
                .orderByDesc(CommDict::getCreateTime)
                .list();
        PageInfo pageInfo = new PageInfo<>(list);
        PageHelper.clearPage();
        pageInfo.setList(getCommDictQueryVos(list));
        return pageInfo;
    }

    @Override
    public List<CommDictQueryVo> dictQueryList(CommDictQueryListParam param) throws Exception {
        List<CommDict> commDictList = commDictDao.lambdaQuery()
                .eq(ObjectUtils.isNotEmpty(param.getTypeId()), CommDict::getTypeId, param.getTypeId())
                .like(StringUtils.isNotBlank(param.getDictKey()), CommDict::getDictKey, param.getDictKey())
                .like(StringUtils.isNotBlank(param.getDictValue()), CommDict::getDictValue, param.getDictValue())
                .orderByDesc(CommDict::getCreateTime)
                .list();
        return getCommDictQueryVos(commDictList);
    }


    private List<CommDictQueryVo> getCommDictQueryVos(List<CommDict> list) throws Exception {
        List<CommDictQueryVo> commDictQueryVoList = new ArrayList<>();
        for (CommDict commDict : list) {
            CommDictQueryVo commDictQueryVo = BeanHelper.copyBean(commDict, CommDictQueryVo.class);
            CommDictType commDictType = commDictTypeDao.getById(commDict.getTypeId());
            if (ObjectUtils.isNotEmpty(commDictType)) {
                commDictQueryVo.setTypeKey(commDictType.getDictTypeKey());
                commDictQueryVo.setTypeName(commDictType.getDictTypeName());
            }
            commDictQueryVoList.add(commDictQueryVo);
        }
        return commDictQueryVoList;
    }
}
